home *** CD-ROM | disk | FTP | other *** search
/ Suzy B Software 2 / Suzy B Software CD-ROM 2 (1994).iso / extras / programm / a56 / src / lex.c < prev    next >
C/C++ Source or Header  |  1995-04-27  |  11KB  |  475 lines

  1. /*******************************************************
  2.  *
  3.  *  a56 - a DSP56001 assembler
  4.  *
  5.  *  Written by Quinn C. Jensen
  6.  *  July 1990
  7.  *
  8.  *******************************************************\
  9.  
  10. /*
  11.  *  lex.c - lexical analyzer envelope.  lexyy.c, included below,
  12.  *  is the LEX-generated code.
  13.  *
  14.  */
  15.  
  16. #include "a56.h"
  17. #include "gram.h"
  18.  
  19. int ldebug = 0;
  20. #ifdef LDEBUG
  21. #define RET(val) \
  22.     {\
  23.         if(ldebug) {\
  24.             printf("[%s]", tok_print(val));\
  25.             fflush(stdout);\
  26.         }\
  27.         return val;\
  28.     }
  29. #else
  30. #define RET(val) {return val;}
  31. #endif
  32.  
  33. extern YYSTYPE yyval;
  34.  
  35. double atof();
  36.  
  37. /**************** yylex - returns next token *****************************/
  38.  
  39. #define MAX_TOK 1024
  40. char tok[MAX_TOK];
  41.  
  42. yylex()
  43. {
  44.     int ltok = next_tok();
  45.     int itok;
  46.  
  47.     switch(ltok) {
  48.     case EOF:
  49.         if(yywrap() == 1)
  50.             return 0;
  51.         else
  52.             return yylex();
  53.         break;
  54.     case SYM:
  55.         if(itok = is_keyword(tok)) {
  56.             RET(itok);
  57.         } else {
  58.             yylval.sval = strsave(tok);
  59.             RET(SYM);
  60.         }
  61.         break;
  62.     case CHEX:
  63.         yylval.n.type = INT;
  64.         yylval.n.val.i = strtol(tok, 0, 16);
  65.         RET(CHEX);
  66.         break;
  67.     case CDEC:
  68.         yylval.n.type= INT;
  69.         yylval.n.val.i = atoi(tok);
  70.         RET(CDEC);
  71.         break;
  72.     case FRAC:
  73.         yylval.n.type = FLT;
  74.         yylval.n.val.f = atof(tok);
  75.         RET(FRAC);
  76.     case CHAR:
  77.         yylval.cval = *tok;
  78.         RET(CHAR);
  79.     case STRING:
  80.         yylval.sval = (char *)fixstring(tok);
  81.         yylval.sval = strsave(yylval.sval);
  82.         RET(STRING);
  83.     default:
  84.         RET(ltok);
  85.     }
  86. }
  87.  
  88. is_keyword(tok)
  89. char *tok;
  90. {
  91.     int kval = kparse(tok);
  92.     if(kval > 0)
  93.         return kval;
  94.  
  95.     return 0;
  96. }
  97.  
  98. struct ascii_tab {
  99.     char *str;
  100.     int flags;
  101. } ascii_tab[];
  102. #define IS_NONE        0x0000
  103. #define IS_NUM        0x0001
  104. #define IS_ALPHA    0x0002
  105. #define IS_HEX        0x0004
  106. #define IS_WHITE    0x0008
  107.  
  108. extern FILE *yyin;
  109.  
  110. int next_tok()
  111. {
  112.     char *tp = tok;
  113.     enum {S_TOP, S_HEXNUM, S_NUM, S_ALNUM, S_CHAR, S_ESC_CHAR, S_COMMENT,
  114.         S_SQ_STRING, S_DQ_STRING, S_SHL, S_SHR} state = S_TOP;
  115.     static int unget = 0;
  116.     BOOL dot_seen = FALSE;
  117.  
  118.     for(;;) {
  119.         int c = unget ? unget : lgetc(yyin);
  120.         int flags;
  121.         unget = 0;
  122.         flags = ascii_tab[c & 0x7F].flags;
  123.         if(tp > tok + MAX_TOK - 2) return LEXBAD;
  124.         switch(state) {
  125.         case S_TOP:
  126.             if(c == EOF) {
  127.                 return EOF;
  128.             } else if(flags & IS_WHITE) {
  129.                 /* ignore */ ;
  130.             } else if(flags & IS_ALPHA) {
  131.                 *tp++ = c;
  132.                 state = S_ALNUM;
  133.             } else if((flags & IS_NUM) || c == '.') {
  134.                 unget = c;
  135.                 state = S_NUM;
  136.             } else {
  137.                 switch(c) {
  138.                 case '$': state = S_HEXNUM; break;
  139.                 case '"': state = S_DQ_STRING; break;
  140.                 case '\'': state = S_CHAR; break;
  141.                 case '>': state = S_SHR; break;
  142.                 case '<': state = S_SHL; break;
  143.                 case ';': state = S_COMMENT; break;
  144.                 case '\n': return EOL;
  145.                 case '@': return EOS;
  146.                 default: return c;
  147.                 }
  148.             }
  149.             break;
  150.         case S_COMMENT:
  151.             if(c == EOF) {
  152.                 unget = EOF;
  153.                 *tp = '\0';
  154.                 return EOL;
  155.             } else if(c == '\n') {
  156.                 return EOL;
  157.             }
  158.             break;
  159.         case S_SHR:
  160.             if(c == EOF) {
  161.                 unget = EOF;
  162.                 *tp = '\0';
  163.                 return '>';
  164.             } else if(c == '>') {
  165.                 return SHR;
  166.             } else {
  167.                 unget = c;
  168.                 return '>';
  169.             }
  170.             break;
  171.         case S_SHL:
  172.             if(c == EOF) {
  173.                 unget = EOF;
  174.                 *tp = '\0';
  175.                 return '<';
  176.             } else if(c == '<') {
  177.                 return SHL;
  178.             } else {
  179.                 unget = c;
  180.                 return '<';
  181.             }
  182.             break;
  183.         case S_HEXNUM:
  184.             if(c == EOF) {
  185.                 unget = EOF;
  186.                 *tp = '\0';
  187.                 return CHEX;
  188.             } else if(flags & IS_HEX) {
  189.                 *tp++ = c;
  190.                 break;
  191.             } else {
  192.                 unget = c;
  193.                 *tp = '\0';
  194.                 return CHEX;
  195.             }
  196.             break;
  197.         case S_ALNUM:
  198.             if(c == EOF) {
  199.                 unget = EOF;
  200.                 *tp = '\0';
  201.                 return SYM;
  202.             } else if(c == ':') {
  203.                 *tp++ = c;
  204.                 *tp = '\0';
  205.                 return SYM;
  206.                 break;
  207.             } else if(flags & (IS_ALPHA|IS_NUM)) {
  208.                 *tp++ = c;
  209.                 break;
  210.             } else {
  211.                 unget = c;
  212.                 *tp = '\0';
  213.                 return SYM;
  214.             }
  215.             break;
  216.         case S_NUM:
  217.             if(c == EOF) {
  218.                 unget = EOF;
  219.                 *tp = '\0';
  220.                 return dot_seen ? FRAC : CDEC;
  221.             } else if((flags & IS_NUM) || (c == '.' && NOT dot_seen)) {
  222.                 *tp++ = c;
  223.                 if(c == '.') dot_seen = TRUE;
  224.                 break;
  225.             } else {
  226.                 unget = c;
  227.                 *tp = '\0';
  228.                 return dot_seen ? FRAC : CDEC;
  229.             }
  230.             break;
  231.         case S_CHAR:
  232.             if(c == EOF) {
  233.                 unget = EOF;
  234.                 *tp = '\0';
  235.                 return CHAR;
  236.             } else if(c == '\\') {
  237.                 state = S_ESC_CHAR;
  238.             } else if(c == '\'') {
  239.                 *tp = '\0';
  240.                 return CHAR;
  241.             } else {
  242.                 *tp++ = c;
  243.                 if(tp > tok + 1)
  244.                     state = S_SQ_STRING;
  245.             }
  246.             break;
  247.         case S_ESC_CHAR:
  248.             if(c == EOF) {
  249.                 unget = EOF;
  250.                 *tp = '\0';
  251.                 return CHAR;
  252.             }
  253.             switch(c) {
  254.             case 'b': *tp = '\b'; break;
  255.             case 'f': *tp = '\f'; break;
  256.             case 'n': *tp = '\n'; break;
  257.             case 'r': *tp = '\r'; break;
  258.             case 't': *tp = '\t'; break;
  259.             case '\\': *tp = '\\'; break;
  260.             case '\'':
  261.                 *tp = '\0';
  262.                 return CHAR;
  263.                 break;
  264.             default:
  265.                 *tp++ = c;
  266.                 state = S_SQ_STRING;
  267.                 break;
  268.             }
  269.             break;
  270.         case S_SQ_STRING:
  271.             if(c == EOF) {
  272.                 unget = EOF;
  273.                 *tp = '\0';
  274.                 return STRING;
  275.             } else if(c == '\'') {
  276.                 *tp = '\0';
  277.                 return STRING;
  278.             } else {
  279.                 *tp++ = c;
  280.             }
  281.             break;
  282.         case S_DQ_STRING:
  283.             if(c == EOF) {
  284.                 unget = EOF;
  285.                 *tp = '\0';
  286.                 return STRING;
  287.             } else if(c == '"') {
  288.                 *tp = '\0';
  289.                 return STRING;
  290.             } else {
  291.                 *tp++ = c;
  292.             }
  293.             break;
  294.         } /* switch(state) */
  295.     } /* for(;;) */
  296. }
  297.  
  298. struct ascii_tab ascii_tab[] = {
  299.     {"\\z00",    IS_NONE                    /* 0x00 */},
  300.     {"\\z01",    IS_NONE                    /* 0x01 */},
  301.     {"\\z02",    IS_NONE                    /* 0x02 */},
  302.     {"\\z03",    IS_NONE                    /* 0x03 */},
  303.     {"\\z04",    IS_NONE                    /* 0x04 */},
  304.     {"\\z05",    IS_NONE                    /* 0x05 */},
  305.     {"\\z06",    IS_NONE                    /* 0x06 */},
  306.     {"\\z07",    IS_NONE                    /* 0x07 */},
  307.     {"\\b",        IS_NONE                    /* 0x08 */},
  308.     {"\\t",        IS_NONE|IS_WHITE        /* 0x09 */},
  309.     {"\\n",        IS_NONE                    /* 0x0A */},
  310.     {"\\z0B",    IS_NONE                    /* 0x0B */},
  311.     {"\\z0C",    IS_NONE                    /* 0x0C */},
  312.     {"\\r",        IS_NONE                    /* 0x0D */},
  313.     {"\\z0E",    IS_NONE                    /* 0x0E */},
  314.     {"\\z0F",    IS_NONE                    /* 0x0F */},
  315.     {"\\z10",    IS_NONE                    /* 0x10 */},
  316.     {"\\z11",    IS_NONE                    /* 0x11 */},
  317.     {"\\z12",    IS_NONE                    /* 0x12 */},
  318.     {"\\z13",    IS_NONE                    /* 0x13 */},
  319.     {"\\z14",    IS_NONE                    /* 0x14 */},
  320.     {"\\z15",    IS_NONE                    /* 0x15 */},
  321.     {"\\z16",    IS_NONE                    /* 0x16 */},
  322.     {"\\z17",    IS_NONE                    /* 0x17 */},
  323.     {"\\z18",    IS_NONE                    /* 0x18 */},
  324.     {"\\z19",    IS_NONE                    /* 0x19 */},
  325.     {"\\z1A",    IS_NONE                    /* 0x1A */},
  326.     {"\\z1B",    IS_NONE                    /* 0x1B */},
  327.     {"\\z1C",    IS_NONE                    /* 0x1C */},
  328.     {"\\z1D",    IS_NONE                    /* 0x1D */},
  329.     {"\\z1E",    IS_NONE                    /* 0x1E */},
  330.     {"\\z1F",    IS_NONE                    /* 0x1F */},
  331.     {" ",        IS_NONE|IS_WHITE        /* 0x20 */},
  332.     {"!",        IS_NONE                    /* 0x21 */},
  333.     {"\"",        IS_NONE                    /* 0x22 */},
  334.     {"#",        IS_NONE                    /* 0x23 */},
  335.     {"$",        IS_NONE                    /* 0x24 */},
  336.     {"%",        IS_NONE                    /* 0x25 */},
  337.     {"&",        IS_NONE                    /* 0x26 */},
  338.     {"'",        IS_NONE                    /* 0x27 */},
  339.     {"(",        IS_NONE                    /* 0x28 */},
  340.     {")",        IS_NONE                    /* 0x29 */},
  341.     {"*",        IS_NONE                    /* 0x2A */},
  342.     {"+",        IS_NONE                    /* 0x2B */},
  343.     {",",        IS_NONE                    /* 0x2C */},
  344.     {"-",        IS_NONE                    /* 0x2D */},
  345.     {".",        IS_NONE                    /* 0x2E */},
  346.     {"/",        IS_NONE                    /* 0x2F */},
  347.     {"0",        IS_NONE|IS_NUM|IS_HEX    /* 0x30 */},
  348.     {"1",        IS_NONE|IS_NUM|IS_HEX    /* 0x31 */},
  349.     {"2",        IS_NONE|IS_NUM|IS_HEX    /* 0x32 */},
  350.     {"3",        IS_NONE|IS_NUM|IS_HEX    /* 0x33 */},
  351.     {"4",        IS_NONE|IS_NUM|IS_HEX    /* 0x34 */},
  352.     {"5",        IS_NONE|IS_NUM|IS_HEX    /* 0x35 */},
  353.     {"6",        IS_NONE|IS_NUM|IS_HEX    /* 0x36 */},
  354.     {"7",        IS_NONE|IS_NUM|IS_HEX    /* 0x37 */},
  355.     {"8",        IS_NONE|IS_NUM|IS_HEX    /* 0x38 */},
  356.     {"9",        IS_NONE|IS_NUM|IS_HEX    /* 0x39 */},
  357.     {":",        IS_NONE                    /* 0x3A */},
  358.     {";",        IS_NONE                    /* 0x3B */},
  359.     {"<",        IS_NONE                    /* 0x3C */},
  360.     {"=",        IS_NONE                    /* 0x3D */},
  361.     {">",        IS_NONE                    /* 0x3E */},
  362.     {"?",        IS_NONE                    /* 0x3F */},
  363.     {"@",        IS_NONE                    /* 0x40 */},
  364.     {"A",        IS_NONE|IS_ALPHA|IS_HEX    /* 0x41 */},
  365.     {"B",        IS_NONE|IS_ALPHA|IS_HEX    /* 0x42 */},
  366.     {"C",        IS_NONE|IS_ALPHA|IS_HEX    /* 0x43 */},
  367.     {"D",        IS_NONE|IS_ALPHA|IS_HEX    /* 0x44 */},
  368.     {"E",        IS_NONE|IS_ALPHA|IS_HEX    /* 0x45 */},
  369.     {"F",        IS_NONE|IS_ALPHA|IS_HEX    /* 0x46 */},
  370.     {"G",        IS_NONE|IS_ALPHA        /* 0x47 */},
  371.     {"H",        IS_NONE|IS_ALPHA        /* 0x48 */},
  372.     {"I",        IS_NONE|IS_ALPHA        /* 0x49 */},
  373.     {"J",        IS_NONE|IS_ALPHA        /* 0x4A */},
  374.     {"K",        IS_NONE|IS_ALPHA        /* 0x4B */},
  375.     {"L",        IS_NONE|IS_ALPHA        /* 0x4C */},
  376.     {"M",        IS_NONE|IS_ALPHA        /* 0x4D */},
  377.     {"N",        IS_NONE|IS_ALPHA        /* 0x4E */},
  378.     {"O",        IS_NONE|IS_ALPHA        /* 0x4F */},
  379.     {"P",        IS_NONE|IS_ALPHA        /* 0x50 */},
  380.     {"Q",        IS_NONE|IS_ALPHA        /* 0x51 */},
  381.     {"R",        IS_NONE|IS_ALPHA        /* 0x52 */},
  382.     {"S",        IS_NONE|IS_ALPHA        /* 0x53 */},
  383.     {"T",        IS_NONE|IS_ALPHA        /* 0x54 */},
  384.     {"U",        IS_NONE|IS_ALPHA        /* 0x55 */},
  385.     {"V",        IS_NONE|IS_ALPHA        /* 0x56 */},
  386.     {"W",        IS_NONE|IS_ALPHA        /* 0x57 */},
  387.     {"X",        IS_NONE|IS_ALPHA        /* 0x58 */},
  388.     {"Y",        IS_NONE|IS_ALPHA        /* 0x59 */},
  389.     {"Z",        IS_NONE|IS_ALPHA        /* 0x5A */},
  390.     {"[",        IS_NONE                    /* 0x5B */},
  391.     {"\\",        IS_NONE                    /* 0x5C */},
  392.     {"]",        IS_NONE                    /* 0x5D */},
  393.     {"^",        IS_NONE                    /* 0x5E */},
  394.     {"_",        IS_NONE|IS_ALPHA        /* 0x5F */},
  395.     {"`",        IS_NONE                    /* 0x60 */},
  396.     {"a",        IS_NONE|IS_ALPHA|IS_HEX    /* 0x61 */},
  397.     {"b",        IS_NONE|IS_ALPHA|IS_HEX    /* 0x62 */},
  398.     {"c",        IS_NONE|IS_ALPHA|IS_HEX    /* 0x63 */},
  399.     {"d",        IS_NONE|IS_ALPHA|IS_HEX    /* 0x64 */},
  400.     {"e",        IS_NONE|IS_ALPHA|IS_HEX    /* 0x65 */},
  401.     {"f",        IS_NONE|IS_ALPHA|IS_HEX    /* 0x66 */},
  402.     {"g",        IS_NONE|IS_ALPHA        /* 0x67 */},
  403.     {"h",        IS_NONE|IS_ALPHA        /* 0x68 */},
  404.     {"i",        IS_NONE|IS_ALPHA        /* 0x69 */},
  405.     {"j",        IS_NONE|IS_ALPHA        /* 0x6A */},
  406.     {"k",        IS_NONE|IS_ALPHA        /* 0x6B */},
  407.     {"l",        IS_NONE|IS_ALPHA        /* 0x6C */},
  408.     {"m",        IS_NONE|IS_ALPHA        /* 0x6D */},
  409.     {"n",        IS_NONE|IS_ALPHA        /* 0x6E */},
  410.     {"o",        IS_NONE|IS_ALPHA        /* 0x6F */},
  411.     {"p",        IS_NONE|IS_ALPHA        /* 0x70 */},
  412.     {"q",        IS_NONE|IS_ALPHA        /* 0x71 */},
  413.     {"r",        IS_NONE|IS_ALPHA        /* 0x72 */},
  414.     {"s",        IS_NONE|IS_ALPHA        /* 0x73 */},
  415.     {"t",        IS_NONE|IS_ALPHA        /* 0x74 */},
  416.     {"u",        IS_NONE|IS_ALPHA        /* 0x75 */},
  417.     {"v",        IS_NONE|IS_ALPHA        /* 0x76 */},
  418.     {"w",        IS_NONE|IS_ALPHA        /* 0x77 */},
  419.     {"x",        IS_NONE|IS_ALPHA        /* 0x78 */},
  420.     {"y",        IS_NONE|IS_ALPHA        /* 0x79 */},
  421.     {"z",        IS_NONE|IS_ALPHA        /* 0x7A */},
  422.     {"{",        IS_NONE                    /* 0x7B */},
  423.     {"|",        IS_NONE                    /* 0x7C */},
  424.     {"}",        IS_NONE                    /* 0x7D */},
  425.     {"~",        IS_NONE                    /* 0x7E */},
  426.     {"\\z7F",    IS_NONE                    /* 0x7F */},
  427. };
  428.  
  429.  
  430. /**************** lgetc - returns next character *************************/
  431.  
  432. #define INLINE 1024
  433.  
  434. char line_buf[INLINE];
  435. char *cur_line = line_buf;        /* points to current line buffer */
  436. char *clp = NULL;                /* where we're at in cur_line */
  437.  
  438. lgetc(fp)
  439. FILE *fp;
  440. {
  441.     int c;
  442.  
  443.     if(clp == NULL) {
  444.         if(fgets(cur_line, INLINE, fp) == NULL) {
  445.             c = EOF;
  446.         } else {
  447.             clp = cur_line;
  448.             c = *clp++;
  449.         }
  450.     } else {
  451.         c = *clp++;
  452.     }
  453.  
  454.     switch(c) {
  455.     case EOF:
  456.         /* at EOF: all done */
  457.         if(ldebug)
  458.             printf("<eof>\n");
  459.         return EOF;
  460.         break;
  461.     case '\0':
  462.         c = '\n';
  463.     case '\n':
  464.         clp = NULL;
  465.         break;
  466.     default:
  467.         break;
  468.     }
  469.  
  470.     if(ldebug)
  471.         printf(c < ' ' ? "<\\z%02X>%s" : "<%c>", c, c == '\n' ? "\n" : "");
  472.  
  473.     return c;
  474. }
  475.